﻿// DlgEstimateML.cpp: 实现文件
//
#include"../../mineObject/mineObject.h"
#include"../../../StdAfx.h"
#include "../../../QuantyView3D.h"
#include "DlgEstimateML.h"
#include "afxdialogex.h"
#include"../../estimation/estimationByML.h"
#include"../../estimation/reserveEstimation.h"
#include<sstream>
#include<fstream>
#include"../../UI/Estimate/resource1.h"
// DlgEstimateML 对话框


vector<MineCube*> in1();
vector<MinePoint*> in();
IMPLEMENT_DYNAMIC(DlgEstimateML, CDialog)

DlgEstimateML::DlgEstimateML(CWnd* pParent /*=nullptr*/)
	: CDialog(IDD_ESTIMATE_ML, pParent)
	, m_parahidenlayer(_T(""))
	, m_paralearningrate(_T(""))
{

}

DlgEstimateML::~DlgEstimateML()
{
}

void DlgEstimateML::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	DDX_Text(pDX, IDC_ParaHidenLayer, m_parahidenlayer);
	DDX_Text(pDX, IDC_ParaLearningRate, m_paralearningrate);
}


BEGIN_MESSAGE_MAP(DlgEstimateML, CDialog)
	
	ON_BN_CLICKED(1, &DlgEstimateML::OnBnClicked1)
	ON_CBN_SELCHANGE(IDC_COMBOTRAINLATER, &DlgEstimateML::OnCbnSelchangeCombotrainlater)
	ON_CBN_SELCHANGE(IDC_COMBOTESTLAYER, &DlgEstimateML::OnCbnSelchangeCombotestlayer)
	ON_EN_SETFOCUS(IDC_ParaHidenLayer, &DlgEstimateML::OnEnSetfocusParahidenlayer)
	ON_WM_CTLCOLOR()
	ON_EN_SETFOCUS(IDC_ParaLearningRate, &DlgEstimateML::OnEnSetfocusParalearningrate)
	
	ON_CBN_SELCHANGE(IDC_COMBOALGORITHM, &DlgEstimateML::OnCbnSelchangeCombo1)
	ON_CBN_SETFOCUS(IDC_COMBOALGORITHM, &DlgEstimateML::OnCbnSetfocusCombo1)
	ON_CBN_EDITCHANGE(IDC_COMBOALGORITHM, &DlgEstimateML::OnCbnEditchangeCombo1)
	ON_CBN_SELENDOK(IDC_COMBOALGORITHM, &DlgEstimateML::OnCbnSelendokCombo1)
END_MESSAGE_MAP()


// DlgEstimateML 消息处理程序

/*
void DlgEstimateML::OnEnChangeParahidenlayer()
{
	// TODO:  如果该控件是 RICHEDIT 控件，它将不
	// 发送此通知，除非重写 CDialog::OnInitDialog()
	// 函数并调用 CRichEditCtrl().SetEventMask()，
	// 同时将 ENM_CHANGE 标志“或”运算到掩码中。

	// TODO:  在此添加控件通知处理程序代码
	GetDlgItem(IDC_ParaHidenLayer)->GetWindowTextA(m_hidel);
	m_para.push_back(m_hidel);
}*/
vector<CString> Return_para(vector<CString>& a)
{
	return a;
}
BOOL DlgEstimateML::OnInitDialog()
{
	CDialog::OnInitDialog();
	// 初始化都为黑色，两个控件的背景都是黑色
	//m_brushEdit = CreateSolidBrush(RGB(255, 255, 255)); ;
	//m_brushList = CreateSolidBrush(RGB(255, 255, 255)); ;

	// TODO:  在此添加额外的初始化
	
	((CComboBox*)GetDlgItem(IDC_COMBOALGORITHM))->AddString("IDW算法");
	((CComboBox*)GetDlgItem(IDC_COMBOALGORITHM))->AddString("BP算法");
	((CComboBox*)GetDlgItem(IDC_COMBOALGORITHM))->AddString("决策树算法");
	((CComboBox*)GetDlgItem(IDC_COMBOALGORITHM))->AddString("随机森林算法");
	((CComboBox*)GetDlgItem(IDC_COMBOALGORITHM))->AddString("SVM算法");
	OnCbnSelchangeCombotestlayer();
	OnCbnSelchangeCombotrainlater();
	//GetDlgItem(IDC_COMBOALGORITHM)->SetWindowTextA("BP算法");
	return TRUE;  // return TRUE unless you set the focus to a control
				  // 异常: OCX 属性页应返回 FALSE
}


void DlgEstimateML::OnBnClicked1()
{
	// TODO: 在此添加控件通知处理程序代码
	UpdateData(TRUE);
	m_parahidenlayer;
	m_paralearningrate;
	//OnCbnSelchangeCombotestlayer();

	CString trainfield;
	CString testfield;
	((CComboBox*)GetDlgItem(IDC_COMBOTRAINLATER))->GetWindowText(trainfield);
	((CComboBox*)GetDlgItem(IDC_COMBOTESTLAYER))->GetWindowText(testfield);

	CString type;//算法类型
	((CComboBox*)GetDlgItem(IDC_COMBOALGORITHM))->GetWindowText(type);
	

	//OnCbnSelchangeCombo1();
	

	for (int i = 0; i < m_parahidenlayer.GetLength(); i++)
	{
		char c;
		c = m_parahidenlayer.GetAt(i);
		if (c >= '0' && c <= '9' || c == '.') {
			//符合数字的条件
		}
		else
		{
			MessageBox("发现非数字存在！ ", "提示 ", MB_OK);
			GetDlgItem(IDC_ParaHidenLayer)->SetWindowTextA("大于0的整数");
			return;
		}

	}
	for (int i = 0; i < m_paralearningrate.GetLength(); i++)
	{
		char c;
		c = m_paralearningrate.GetAt(i);
		if (c >= '0' && c <= '9' || c == '.') {
			//符合数字的条件
		}
		else
		{
			MessageBox("发现非数字存在！ ", "提示 ", MB_OK);
			GetDlgItem(IDC_ParaLearningRate)->SetWindowTextA("0到1之间的小数）");
			return;
		}

	}
	CGV3dDocument* pDoc = (CGV3dDocument*)view->GetDocument();
	ASSERT_VALID(pDoc);
	CGV3dMap* pMap = pDoc->m_Project.GetCurrentMap();//获得当前图幅	
	if (!pMap)
	{
		AfxMessageBox("请设置当前图幅！");
		return;
	}

	MineLayer* pTrainLayer = (MineLayer*)pMap->GetLayer(trainfield);
	if (!pTrainLayer)
	{
		AfxMessageBox("训练区不存在，请重新选择！");
		return;
	}

	
	
	
	
	//测试封上
	vector<MinePoint*> trainpoints=pTrainLayer->getAllPoint();
	
	//测试拆封
	//vector<MinePoint*> trainpoints= in();

	string in = EstimationByML::GetInputTXT(trainpoints);


	MineLayer* pTestLayer = (MineLayer*)pMap->GetLayer(testfield);
	if (!pTestLayer)
	{
		AfxMessageBox("测试区不存在，请重新选择！");
		return;
	}

	//测试封上
	
	//pTestLayer = new MineLayer;
	vector<CGV3dObject*> testobjs;
	testobjs = pTestLayer->getAllObject();
	vector<MineCube*> testcube;
	
	int objectnumber = 0;
	if (pTestLayer)
	{
		objectnumber= pTestLayer->GetCount();
	}
	
	
	for (auto i = 0; i < objectnumber; i++)
	{
		CGV3dObject* obj = pTestLayer->GetObjectAt(i);
		if (obj->GetClass() == CLASS_MINE_CUBE)
		{
			testcube.push_back((MineCube*)obj);
		}

	}
	

	//测试拆封
	//vector<MineCube*> testcube = in1();
	
	string out = EstimationByML::GetEstimateTXT(testcube);


	int layer;
	layer = _ttoi(m_parahidenlayer);
	double lr;
	lr = atof(m_paralearningrate);
	string prar;


	if(type== "BP算法"){
		prar = EstimationByML::GetBPPara(layer, lr);
		prar += "0";
		ReserveEstimation::estimationBySklearn(trainpoints, testcube, prar);
		vector<string> s=EstimationByML::ReturnEvaluate();
		CString ss;
		CString box;
		CString e;
		e.Format("\r\n");
		for (int i = 0; i < s.size(); i++)
		{
			ss = s[i].c_str()+e;
			box += ss;
		}
		EstimationByML::setResult(testcube);
		AfxMessageBox(box);
	}
	if (type == "决策树算法") {
		prar = EstimationByML::GetDTreePara(layer);
		prar += "1";
		ReserveEstimation::estimationBySklearn(trainpoints, testcube, prar);
		vector<string> s = EstimationByML::ReturnEvaluate();
		CString ss;
		CString box;
		CString e;
		e.Format("\r\n");
		for (int i = 0; i < s.size(); i++)
		{
			ss = s[i].c_str() + e;
			box += ss;
		}
		AfxMessageBox(box);
		EstimationByML::setResult(testcube);
	}
	if (type == "随机森林算法") {
		prar = EstimationByML::GetRTreePara(layer);
		prar += "2";
		ReserveEstimation::estimationBySklearn(trainpoints, testcube, prar);
		vector<string> s = EstimationByML::ReturnEvaluate();
		CString ss;
		CString box;
		CString e;
		e.Format("\r\n");
		for (int i = 0; i < s.size(); i++)
		{
			ss = s[i].c_str() + e;
			box += ss;
		}
		AfxMessageBox(box);
		EstimationByML::setResult(testcube);
	}
	if (type == "SVM算法") {
		prar = EstimationByML::GetSVMPara(lr);
		prar += "3";
		ReserveEstimation::estimationBySklearn(trainpoints, testcube, prar);
		vector<string> s = EstimationByML::ReturnEvaluate();
		CString ss;
		CString box;
		CString e;
		e.Format("\r\n");
		for (int i = 0; i < s.size(); i++)
		{
			ss = s[i].c_str() + e;
			box += ss;
		}
		AfxMessageBox(box);
		EstimationByML::setResult(testcube);
	}


	if (type == "IDW算法") {
		/*参数？？？？？*/
		double arg = atof(m_parahidenlayer);
		
		double dis=atof(m_paralearningrate);
		ReserveEstimation::estimationByIDW(trainpoints, testcube,arg,dis);
		AfxMessageBox("计算完毕");

	}

	
	




	//ReserveEstimation::estimationBySklearn(tr, cu,prar);
	//EstimationByML::setResult(testcube);

	

	DlgEstimateML::OnOK();
}

/*
void DlgEstimateML::OnEnChangeParalearningrate()
{
	// TODO:  如果该控件是 RICHEDIT 控件，它将不
	// 发送此通知，除非重写 CDialog::OnInitDialog()
	// 函数并调用 CRichEditCtrl().SetEventMask()，
	// 同时将 ENM_CHANGE 标志“或”运算到掩码中。
	// TODO:  在此添加控件通知处理程序代码
	GetDlgItem(IDC_ParaLearningRate)->GetWindowText(m_lr);

	m_para.insert(m_para.begin(),m_lr);
}*/


/*
void DlgEstimateML::OnEnChangeMinetypr()
{
	// TODO:  如果该控件是 RICHEDIT 控件，它将不
	// 发送此通知，除非重写 CDialog::OnInitDialog()
	// 函数并调用 CRichEditCtrl().SetEventMask()，
	// 同时将 ENM_CHANGE 标志“或”运算到掩码中。

	// TODO:  在此添加控件通知处理程序代码
	GetDlgItem(IDC_ParaHidenLayer)->GetWindowText(m_mine_type);
	m_mine_type.Format(TEXT("%s"));
	m_para.insert(m_para.begin()+1, m_mine_type);
}*/


void DlgEstimateML::OnCbnSelchangeCombotrainlater()
{
	// TODO: 在此添加控件通知处理程序代码
	//EstimationByML::Getatg(Return_para(m_para));
	
	CGV3dDocument* pDoc = (CGV3dDocument*)view->GetDocument();
	ASSERT_VALID(pDoc);
	CGV3dMap* pMap = pDoc->m_Project.GetCurrentMap();//获得当前图幅	
	if (!pMap)
	{
		AfxMessageBox("请设置当前图幅！");
		return;
	}

	int count_layer = pMap->GetCount();
	vector<MineLayer*> layers;
	for (int i = 0; i < count_layer; i++)
	{
		CGV3dLayer* la = pMap->GetLayerAt(i);

		if (la->GetClass() == CLASS_MINE_LAYER)
		{
			layers.push_back((MineLayer*)la);
			((CComboBox*)GetDlgItem(IDC_COMBOTRAINLATER))->AddString(la->GetName());
		}
		//AfxMessageBox(la->GetName());
		
	}

}


void DlgEstimateML::OnCbnSelchangeCombotestlayer()
{
	// TODO: 在此添加控件通知处理程序代码
	//EstimationByML::Getatg(Return_para(m_para));
	
	CGV3dDocument* pDoc = (CGV3dDocument*)view->GetDocument();
	ASSERT_VALID(pDoc);
	CGV3dMap* pMap = pDoc->m_Project.GetCurrentMap();//获得当前图幅	
	if (!pMap)
	{
		AfxMessageBox("请设置当前图幅！");
		return;
	}
	
	int count_layer = pMap->GetCount();
	vector<MineLayer*> layers;
	for (int i = 0; i < count_layer; i++)
	{
		CGV3dLayer* la = pMap->GetLayerAt(i);

		if (la->GetClass() == CLASS_MINE_LAYER)
		{
			layers.push_back((MineLayer*)la);
			((CComboBox*)GetDlgItem(IDC_COMBOTESTLAYER))->AddString(la->GetName());
		}
		//AfxMessageBox(la->GetName());
		
	}
}


void DlgEstimateML::OnEnSetfocusParahidenlayer()
{
	// TODO: 在此添加控件通知处理程序代码
	GetDlgItem(IDC_ParaHidenLayer)->SetWindowTextA(""); 
	
}




HBRUSH DlgEstimateML::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
	HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);

	// TODO:  在此更改 DC 的任何特性

	/*
	// TODO: Change any attributes of the DC here  
	switch (nCtlColor) //对所有同一类型的控件进行判断  
	{
	case CTLCOLOR_EDIT:
	case CTLCOLOR_LISTBOX://假设控件是文本框或者列表框，则进入下一个switch  
		switch (pWnd->GetDlgCtrlID())			//对某一个特定控件进行判断  
		{
			// first CEdit control ID  
		case IDC_ParaHidenLayer:							// 第一个文本框 
		{
			pDC->SetBkColor(RGB(255,255,255));		// change the background(已经绘制文字的背景)
			pDC->SetTextColor(RGB(192, 192, 192));	// change the text color（文字颜色）
			hbr = (HBRUSH)m_brushEdit;			// apply the brush （未绘制文字的背景）
			break;
		}

		case IDC_ParaLearningRate:				// 第二个文本框  
		{
			pDC->SetBkColor(RGB(255, 255, 255));		// change the background(已经绘制文字的背景)
			pDC->SetTextColor(RGB(192, 192, 192));	// change the text color（文字颜色）
			hbr = (HBRUSH)m_brushList;			// apply the brush  （未绘制文字的背景）
			break;
		}

		default:
			hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
			break;
		}
		break;
	}
	*/

	// TODO:  如果默认的不是所需画笔，则返回另一个画笔
	return hbr;
}


void DlgEstimateML::OnEnSetfocusParalearningrate()
{
	// TODO: 在此添加控件通知处理程序代码
	GetDlgItem(IDC_ParaLearningRate)->SetWindowTextA("");
}




void DlgEstimateML::OnCbnSelchangeCombo1()
{
	// TODO: 在此添加控件通知处理程序代码
	CString type;//算法类型
	((CComboBox*)GetDlgItem(IDC_COMBOALGORITHM))->GetWindowText(type);
	if (type == "BP算法")
	{
		GetDlgItem(IDC_ParaHidenLayer)->SetWindowTextA("大于0的整数");
		GetDlgItem(IDC_ParaLearningRate)->SetWindowTextA("0到1之间的小数）");
		GetDlgItem(IDC_STATICFIRST)->SetWindowTextA("隐藏层数");
		GetDlgItem(IDC_STATICSE)->SetWindowTextA("学习率");
		GetDlgItem(IDC_ParaLearningRate)->ShowWindow(TRUE);
		GetDlgItem(IDC_ParaHidenLayer)->ShowWindow(TRUE);

	}
	if (type == "决策树算法")
	{
		GetDlgItem(IDC_ParaHidenLayer)->SetWindowTextA("大于0的整数");
		GetDlgItem(IDC_STATICFIRST)->SetWindowTextA("最大深度");
		GetDlgItem(IDC_ParaLearningRate)->ShowWindow(FALSE);
		int bVisible = ((CWnd*)GetDlgItem(IDC_ParaHidenLayer))->GetStyle() & WS_VISIBLE;
		if (bVisible == 0)
		{
			GetDlgItem(IDC_ParaHidenLayer)->ShowWindow(TRUE);

		}
		GetDlgItem(IDC_STATICSE)->SetWindowTextA("");
	}
	if (type == "随机森林算法")
	{
		GetDlgItem(IDC_ParaHidenLayer)->SetWindowTextA("大于0的整数");
		GetDlgItem(IDC_STATICFIRST)->SetWindowTextA("树的数量");
		GetDlgItem(IDC_ParaLearningRate)->ShowWindow(FALSE);
		int bVisible = ((CWnd*)GetDlgItem(IDC_ParaHidenLayer))->GetStyle() & WS_VISIBLE;
		if (bVisible == 0)
		{
			GetDlgItem(IDC_ParaHidenLayer)->ShowWindow(TRUE);

		}
		//GetDlgItem(IDC_ParaLearningRate)->ShowWindow(FALSE);
		GetDlgItem(IDC_STATICSE)->SetWindowTextA("");
	}
	if (type == "SVM算法")
	{
		GetDlgItem(IDC_STATICFIRST)->SetWindowTextA("");
		GetDlgItem(IDC_ParaHidenLayer)->ShowWindow(FALSE);
		int bVisible = ((CWnd*)GetDlgItem(IDC_ParaLearningRate))->GetStyle() & WS_VISIBLE;
		if (bVisible == 0)
		{
			GetDlgItem(IDC_ParaLearningRate)->ShowWindow(TRUE);

		}
		GetDlgItem(IDC_STATICSE)->SetWindowTextA("惩罚系数");
	}


	if (type == "IDW算法")
	{
		//int bVisible1 = ((CWnd*)GetDlgItem(IDC_ParaLearningRate))->GetStyle() & WS_VISIBLE;
		//int bVisible2 = ((CWnd*)GetDlgItem(IDC_ParaHidenLayer))->GetStyle() & WS_VISIBLE;

		GetDlgItem(IDC_STATICFIRST)->SetWindowTextA("距离次数");
		GetDlgItem(IDC_STATICSE)->SetWindowTextA("搜索窗口边长");
		GetDlgItem(IDC_ParaLearningRate)->ShowWindow(TRUE);
		GetDlgItem(IDC_ParaHidenLayer)->ShowWindow(TRUE);		
		
		GetDlgItem(IDC_ParaHidenLayer)->SetWindowTextA("大于0的小数");
		GetDlgItem(IDC_ParaLearningRate)->SetWindowTextA("大于0的小数）");

	}
	UpdateData(FALSE);
}


void DlgEstimateML::OnCbnSetfocusCombo1()
{
	// TODO: 在此添加控件通知处理程序代码
	//OnCbnSelchangeCombo1();
}


void DlgEstimateML::OnCbnEditchangeCombo1()
{
	// TODO: 在此添加控件通知处理程序代码
	OnCbnSelchangeCombo1();
	//UpdateData(TRUE);
}


void DlgEstimateML::OnCbnSelendokCombo1()
{
	// TODO: 在此添加控件通知处理程序代码
}

vector<MinePoint*> in()
{
	ifstream in;
	in.open("E:\\627\\code2\\mini-mine-digital-mine-system\\QuantyView3D_SDK\\build\\3DFrame\\QuantyView3d\\pyscript\\da.csv");
	vector<MinePoint*> p;
	if (in.eof())
	{
		//return NULL;
		return p;
	}
	string line;
	getline(in, line);
	//vector<MinePoint*> p;
	while (getline(in, line))
	{
		string field;
		istringstream sin(line);
		getline(sin, field, ',');
		double x = atof(field.c_str());
		getline(sin, field, ',');
		double y = atof(field.c_str());
		getline(sin, field, ',');
		double z = atof(field.c_str());
		getline(sin, field);
		double g = atof(field.c_str());

		MinePoint* p1 = new MinePoint;
		XYZ po = {x,y,z};
		p1->setXYZ(po);
		p1->setGrade(g);
		p.push_back(p1);
	}
	in.close();

	return p;
}
vector<MineCube*> in1()
{
	ifstream in;	
	vector<MineCube*> cubes;
	in.open("E:\\627\\code2\\mini-mine-digital-mine-system\\QuantyView3D_SDK\\build\\3DFrame\\QuantyView3d\\pyscript\\te.csv");
	if (in.eof())
	{
		//return NULL;
		return cubes;
	}
	string line;


	getline(in, line);
	while (getline(in, line))
	{
		string field;
		istringstream sin(line);
		getline(sin, field, ',');
		double x = atof(field.c_str());
		getline(sin, field, ',');
		double y = atof(field.c_str());
		getline(sin, field, ',');
		double z = atof(field.c_str());
		getline(sin, field);
		double g = atof(field.c_str());

		MineCube* p1 = new MineCube;
		XYZ po = { x,y,z };
		p1->setObject(po, g);
		p1->setGrade(g);
		cubes.push_back(p1);
	}
	in.close();

	return cubes;
}

